package com.wind.wx;

import com.wind.util.AESUtil;
import com.wind.util.ClientCustomSSL;
import com.wind.util.CommonConst;
import com.wind.util.OrderNumEngender;
import org.jdom2.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.*;

public class Weipayment {

	//测试
	//static final String NOTIFY_URL = "";
	static final String BUY_NOTIFY_URL = "http://39.108.209.85:8008/api/v1/order/notify";
	//static final String REFUND_URL = "http://39.108.209.85:8008/api/v1/order/notify";
	static final String FULL_REFUND_URL = "http://39.108.209.85:8008/api/v1/order/refund";

	protected static Logger logger = LoggerFactory.getLogger(Weipayment.class);

	/**
	 * OK
	 */
	public static final String res_OK_Xml= "<xml>"
			+ "<return_code><![CDATA[SUCCESS]]></return_code>"
			+ "<return_msg><![CDATA[OK]]></return_msg>"
			+ "</xml> ";	
	/**
	 * 参数错误
	 */
	public static final String res_error_para = "<xml>"
			+ "<return_code><![CDATA[FAIL]]></return_code>"
			+ "<return_msg><![CDATA[参数错误]]></return_msg>"
			+ "</xml> ";
	/**
	 * 报文为空
	 */
	private static final String res_message_null = "<xml>"
			+ "<return_code><![CDATA[FAIL]]></return_code>"
			+ "<return_msg><![CDATA[报文为空]]></return_msg>"
			+ "</xml> ";
	/**
	 * 通知签名验证失败
	 */
	private static final String res_signature_fail = "<xml>"
			+ "<return_code><![CDATA[FAIL]]></return_code>"
			+ "<return_msg><![CDATA[通知签名验证失败]]></return_msg>"
			+ "</xml> ";


	public static Map<String, String> doProcessPost(String appId,String openId,String trade_type,String ip,int price100,String orderNum){
		try {
			String nonceStr = PayCommonUtil.CreateNoncestr();
			SortedMap<String, Object> parameters = new TreeMap<>();
			parameters.put("appid", appId);
			parameters.put("mch_id", WeiXinConfig.MCH_ID);// 商户号
			parameters.put("nonce_str",nonceStr);
			parameters.put("body", "心口网络商品购买");
			parameters.put("out_trade_no", orderNum); // 订单id
			parameters.put("fee_type", "CNY");
			//parameters.put("total_fee", String.valueOf(price100));
			parameters.put("total_fee", String.valueOf(1));
			parameters.put("notify_url", BUY_NOTIFY_URL);
			if(trade_type.equals("JSAPI")) {
				parameters.put("openid", openId);
			}
			if(Objects.nonNull(ip)) {
				parameters.put("spbill_create_ip", ip); 
			}
			parameters.put("trade_type", trade_type);
			// 设置签名
			String sign = PayCommonUtil.createSign(CommonConst.CHARSET_UTF8, parameters,WeiXinConfig.API_KEY);
			parameters.put("sign", sign);
			// 封装请求参数结束
			String requestXML = PayCommonUtil.getRequestXml(parameters);
			// 调用统一下单接口
			Map<String, String> result= XMLUtil.doXMLParse(PayCommonUtil.httpsRequest(WeiXinConfig.UNIFIED_ORDER_URL, CommonConst.POST, requestXML));
			result.put("nonceStr", nonceStr);
			return result;
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}


	/**
     * 调用微信超时未发货退款
     * @param price100
     * @param orderNo
     * @param isFullRefund true回调地址为订单全额退款，false为子订单退款
     * @return
    */
	public static boolean doRefundPost(BigDecimal price100, BigDecimal totalPrice100,String orderNo ,String paymentNo,boolean isFullRefund){

		SortedMap<String, Object> parameters = new TreeMap<>();
		parameters.put("appid", WeiXinConfig.APPID);

		parameters.put("mch_id", WeiXinConfig.MCH_ID);// 商户号
		parameters.put("nonce_str", PayCommonUtil.CreateNoncestr());
		parameters.put("out_trade_no", paymentNo); // 与支付的 交易号一致
		//更换为支付no
		parameters.put("out_refund_no", orderNo);
		parameters.put("total_fee", String.valueOf(totalPrice100.intValue()));
		parameters.put("refund_desc", "商品退款");
		parameters.put("refund_fee", String.valueOf(price100.intValue()));
		parameters.put("refund_fee_type", "CNY");
		if(isFullRefund){
			parameters.put("notify_url", FULL_REFUND_URL);
		}

		// 设置签名
		String sign = PayCommonUtil.createSign(CommonConst.CHARSET_UTF8, parameters,WeiXinConfig.API_KEY);
		parameters.put("sign", sign);

		// 封装请求参数结束
		String requestXML = PayCommonUtil.getRequestXml(parameters);

		// 调用统一下单接口
		try {
			ClientCustomSSL.doRefund(WeiXinConfig.REFUND_ORDER_URL, requestXML);
			return true;
		} catch (Exception e) {
			logger.error("调微信统一下单 发生异常", e);
		}
		return false;
	}


	public static Map<String, Object> parseRefundMap(InputStream in){
		Map<String, Object> resultMap = new HashMap<>();

		Map<String, String> m = new HashMap<>();
		try {
			String s;
			StringBuilder sb = new StringBuilder();
			BufferedReader br = new BufferedReader(new InputStreamReader(in, CommonConst.CHARSET_UTF8));
			while ((s = br.readLine()) != null) {
				sb.append(s);
			}
			br.close();
			in.close();
			// 解析xml成map
			m = XMLUtil.doXMLParse(sb.toString());
		} catch (Exception e) {
			logger.error("parseParaMap", e);
		}
		// 过滤空 设置 TreeMap
		SortedMap<String, String> packageParams = new TreeMap<>();
		Iterator<String> it = m.keySet().iterator();
		while (it.hasNext()) {
			String parameter = it.next();
			String parameterValue = m.get(parameter);

			String v = "";
			if (null != parameterValue) {
				v = parameterValue.trim();
			}
			packageParams.put(parameter, v);
		}
		/*
		 * 解密req_info
		 */
		if ("SUCCESS".equals( packageParams.get("return_code"))) {
	        try {
				m = XMLUtil.doXMLParse(AESUtil.decryptData(packageParams.get("req_info")));
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
	        it = m.keySet().iterator();
			while (it.hasNext()) {
				String parameter =  it.next();
				String parameterValue = m.get(parameter);

				String v = "";
				if (null != parameterValue) {
					v = parameterValue.trim();
				}
				packageParams.put(parameter, v);
			}
			//
			if ("SUCCESS".equals( packageParams.get("refund_status"))) {
				// 这里是支付成功
				WechatOrder wechatOrder = new WechatOrder();
				wechatOrder.setMchId(packageParams.get("mch_id"));
				wechatOrder.setOutTradeNo(packageParams.get("out_trade_no"));
				wechatOrder.setTotalFee(new BigDecimal(packageParams.get("total_fee")));
				wechatOrder.setRefundFee(new BigDecimal(packageParams.get("refund_fee")));
				wechatOrder.setOutRefundNo(packageParams.get("out_refund_no"));
				wechatOrder.setTransactionId(packageParams.get("transaction_id"));
				resultMap.put("status", "success");
				resultMap.put("data", wechatOrder);
				return resultMap;
			} else {// 返回不是SUCCESS
				resultMap.put("status", "error");
				resultMap.put("data", res_message_null);
			}
		} else {// 错误
			resultMap.put("status", "error");
			resultMap.put("data", res_error_para);
		}

		return resultMap;
	}

	/**
	 * 统一下单
	 * @param type
	 * @return
	 */
	private static String getResult(int type,int price100,String orderNum){
		SortedMap<String, Object> parameters = new TreeMap<>();
		String body ;
		if(type == 1) {
			body = "心口网络商品购买";
		} else {
			body = "心口网络商品购买";
		}
		parameters.put("appid", WeiXinConfig.APPID);
		parameters.put("mch_id", WeiXinConfig.MCH_ID);// 商户号
		parameters.put("nonce_str", PayCommonUtil.CreateNoncestr());
		parameters.put("body", body);
		parameters.put("out_trade_no", orderNum); // 订单id
		parameters.put("fee_type", "CNY");
		//parameters.put("total_fee", String.valueOf(price100));
		parameters.put("total_fee", String.valueOf(1));
		if(type==2){
			parameters.put("notify_url", BUY_NOTIFY_URL);
			logger.info("notify_url-->" + BUY_NOTIFY_URL);
		}
		parameters.put("trade_type", "APP");

		// 设置签名
		String sign = PayCommonUtil.createSign(CommonConst.CHARSET_UTF8, parameters,WeiXinConfig.API_KEY);
		parameters.put("sign", sign);

		// 封装请求参数结束
		String requestXML = PayCommonUtil.getRequestXml(parameters);

		// 调用统一下单接口
		return  PayCommonUtil.httpsRequest(WeiXinConfig.UNIFIED_ORDER_URL, CommonConst.POST, requestXML);
	}
}
